# 基于yapi搭建接口文档

# 功能介绍

  1. 基于swagger快速生成文档,通用绝大数语言
  2. 可一键生成ts请求代码
  3. 可自动mock
  4. 支持多项目、多分类,成员管理
  5. 对接口自动化测试(未测试功能有效性)

image-20230730165231935

# 部署

  1. 使用官方脚手架(已经无人维护,出现很多报错,不推荐使用)

  2. 使用docker安装:https://github.com/fjc0k/docker-YApi

    一键安装

# php转swagger

需phper想办法解决

同时,后台的代码也能通过这种方式展示文档

# 自动同步接口文档

yapi自带功能,配置一个与文档部署环境互通的环境即可

# 接口转ts请求代码

https://fjc0k.github.io/yapi-to-typescript/handbook/config.html

使用yapi-to-typescript,可直接获取yapi对应项目的接口,通过简单配置即可生成前端需要的接口类型及请求函数,再也不需要对着文档手敲了。

import { defineConfig } from 'yapi-to-typescript'

export default defineConfig([
  {
    serverUrl: 'http://127.0.0.1:40001',
    typesOnly: false,
    target: 'typescript',
    reactHooks: {
      enabled: false,
    },
    prodEnvName: 'production',
    outputFilePath: 'src/api/path/index.ts',
    requestFunctionFilePath: 'src/api/request.ts',
    dataKey: 'data',
    projects: [
      {
        token: 'f92640661e5c7207365dd7c2b6de55daa6743af054e41d0a050e631edd7887df',
        categories: [
          {
            id: 79,
            getRequestFunctionName(interfaceInfo, changeCase) {
              // 以接口全路径生成请求函数名
              return changeCase.camelCase(interfaceInfo.path)

              // 若生成的请求函数名存在语法关键词报错、或想通过某个关键词触发 IDE 自动引入提示,可考虑加前缀,如:
              // return changeCase.camelCase(`api_${interfaceInfo.path}`)

              // 若生成的请求函数名有重复报错,可考虑将接口请求方式纳入生成条件,如:
              // return changeCase.camelCase(`${interfaceInfo.method}_${interfaceInfo.path}`)
            },
          },
        ],
      },
    ],
  },
])

加到package.json中

"scripts": {
  "ytt": "ytt"
}

生成代码示例:

/* prettier-ignore-start */
/* tslint:disable */
/* eslint-disable */

/* 该文件由 yapi-to-typescript 自动生成,请勿直接修改!!! */

// @ts-ignore
// prettier-ignore
import { QueryStringArrayFormat, Method, RequestBodyType, ResponseBodyType, FileData, prepare } from 'yapi-to-typescript'
// @ts-ignore
// prettier-ignore
import type { RequestConfig, RequestFunctionRestArgs } from 'yapi-to-typescript'
// @ts-ignore
import request from '../request'

type UserRequestRestArgs = RequestFunctionRestArgs<typeof request>

// Request: 目前 React Hooks 功能有用到
export type Request<
  TRequestData,
  TRequestConfig extends RequestConfig,
  TRequestResult,
> = (TRequestConfig['requestDataOptional'] extends true
  ? (requestData?: TRequestData, ...args: RequestFunctionRestArgs<typeof request>) => TRequestResult
  : (requestData: TRequestData, ...args: RequestFunctionRestArgs<typeof request>) => TRequestResult) & {
  requestConfig: TRequestConfig
}

const mockUrl_0_0_0_0 = 'http://127.0.0.1:40001/mock/19' as any
const devUrl_0_0_0_0 = '' as any
const prodUrl_0_0_0_0 = '' as any
const dataKey_0_0_0_0 = 'data' as any

/**
 * 接口 [查询↗](http://127.0.0.1:40001/project/19/interface/api/1601) 的 **请求类型**
 *
 * @分类 [路径链↗](http://127.0.0.1:40001/project/19/interface/api/cat_79)
 * @请求头 `POST /search`
 * @更新时间 `2023-07-30 11:20:12`
 */
export interface SearchRequest {
  /**
   * 链路id
   */
  id: number
}

/**
 * 接口 [查询↗](http://127.0.0.1:40001/project/19/interface/api/1601) 的 **返回类型**
 *
 * @分类 [路径链↗](http://127.0.0.1:40001/project/19/interface/api/cat_79)
 * @请求头 `POST /search`
 * @更新时间 `2023-07-30 11:20:12`
 */
export interface SearchResponse {
  success: boolean
  list: {
    a: string
  }[]
}

/**
 * 接口 [查询↗](http://127.0.0.1:40001/project/19/interface/api/1601) 的 **请求配置的类型**
 *
 * @分类 [路径链↗](http://127.0.0.1:40001/project/19/interface/api/cat_79)
 * @请求头 `POST /search`
 * @更新时间 `2023-07-30 11:20:12`
 */
type SearchRequestConfig = Readonly<
  RequestConfig<'http://127.0.0.1:40001/mock/19', '', '', '/search', 'data', string, string, false>
>

/**
 * 接口 [查询↗](http://127.0.0.1:40001/project/19/interface/api/1601) 的 **请求配置**
 *
 * @分类 [路径链↗](http://127.0.0.1:40001/project/19/interface/api/cat_79)
 * @请求头 `POST /search`
 * @更新时间 `2023-07-30 11:20:12`
 */
const searchRequestConfig: SearchRequestConfig = /*#__PURE__*/ {
  mockUrl: mockUrl_0_0_0_0,
  devUrl: devUrl_0_0_0_0,
  prodUrl: prodUrl_0_0_0_0,
  path: '/search',
  method: Method.POST,
  requestHeaders: {},
  requestBodyType: RequestBodyType.json,
  responseBodyType: ResponseBodyType.json,
  dataKey: dataKey_0_0_0_0,
  paramNames: [],
  queryNames: [],
  requestDataOptional: false,
  requestDataJsonSchema: {},
  responseDataJsonSchema: {},
  requestFunctionName: 'search',
  queryStringArrayFormat: QueryStringArrayFormat.brackets,
  extraInfo: {},
}

/**
 * 接口 [查询↗](http://127.0.0.1:40001/project/19/interface/api/1601) 的 **请求函数**
 *
 * @分类 [路径链↗](http://127.0.0.1:40001/project/19/interface/api/cat_79)
 * @请求头 `POST /search`
 * @更新时间 `2023-07-30 11:20:12`
 */
export const search = /*#__PURE__*/ (requestData: SearchRequest, ...args: UserRequestRestArgs) => {
  return request<SearchResponse>(prepare(searchRequestConfig, requestData), ...args)
}

search.requestConfig = searchRequestConfig

/* prettier-ignore-end */

request

import type { RequestFunctionParams } from 'yapi-to-typescript'

export interface RequestOptions {
  /**
   * 使用的服务器。
   *
   * - `prod`: 生产服务器
   * - `dev`: 测试服务器
   * - `mock`: 模拟服务器
   *
   * @default prod
   */
  server?: 'prod' | 'dev' | 'mock',
}

export default function request<TResponseData>(
  payload: RequestFunctionParams,
  options: RequestOptions = {
    server: 'prod',
  },
): Promise<TResponseData> {
  return new Promise<TResponseData>((resolve, reject) => {
    // 基本地址
    const baseUrl = options.server === 'mock'
      ? payload.mockUrl
      : options.server === 'dev'
        ? payload.devUrl
        : payload.prodUrl

    // 请求地址
    const url = `${baseUrl}${payload.path}`

    // 具体请求逻辑
  })
}

# mock数据

yapi自带mock功能

通过对yapi-to-typescript生成的request文件简单封装即可实现mock数据,再也不需要去项目中手动创建mock了。